/*
 * 文件名称：AppTimer.h
 * 文件描述：提供应用程序定时功能，并执行定时回调函数
 * 作者信息：Satan-Emperor
 * 版本信息：V1.0.0
 * 修改历史：2014-04-22
 */

#ifndef _APPTIMER_H_
#define _APPTIMER_H_

#include <stdint.h>
#include <list>
#include <sys/time.h>
#include <pthread.h>

#include "AppThread.h"

/* 自动分配定时器ID */
#define TIMER_ID_AUTO		0

/* 最大的定时器个数 */
#define MAX_TIMER_CNT		32

enum TIMER_TYPE
{
    TIMER_TYPE_ONESHOT,		/* 只定时一次 */
    TIMER_TYPE_INTERVAL,	/* 循环间隔定时 */
};

/* 函数指针，它是一个指针，用*与函数是否括起来区别 */
typedef bool (*TimerHandle)(int, void *);

/* 定时器信息结构体 */
typedef struct tagTimerInfo
{
    int timerId;		/* 定时器ID,标识不同的定时器 */
    uint64_t baseTime;	/* 基准时间，设置定时器时的时间 */
    uint64_t elapse;	/* 定时时间 */
    int type;			/* 定时器类型，一次/多次 */
    TimerHandle handle;	/* 回调函数指针 */
    void *pParam;		/* 回调函数的参数 */
} TimerInfo;

/* 应用程序定时器类 */
class AppTimer
{
public:
    AppTimer(void);
    virtual ~AppTimer();

public:
	/* 设置定时器 */
    int setTimer(int timerId, int type, int elapse, TimerHandle handle, void *pParam);
    int resetTimer(int timerId);				/* 重置定时器 */
    int killTimer(int timerId);					/* 删除定时器 */
    void run(void);								/* 运行遍历各定时器 */

public:
    static long long getmSecond();				/* 获取从1970年到现在的毫秒数 */
    static time_t getSecond();					/* 获取从1970年到现在的秒数 */

protected:
    int getTimerId(void);						/* 自动生成定时器ID */
    uint64_t getCpuTick(void);					/* 获取CPU的滴答数 */
    static void *timerThreadFunc(void *param);	/* 定时器线程，只用来累加滴答数 */

private:
	/* 定时器ID池 */
    typedef struct tagTimerIdPool
    {
        int id;									/* 定时器ID */
        int state; // 0=free 1=use				/* 状态，0：空闲；1：使用中 */
    } TimerIdPool;

private:
    std::list<TimerInfo> mTimerList;			/* 定时器信息链表 */
    TimerIdPool mTimerIdPool[MAX_TIMER_CNT];	/* 定时器ID池数组 */
    pthread_mutex_t mTimerMutex;				/* 定时器互斥锁，用户互斥访问定时器 */

    AppThread mTimerThread;						/* 定时器线程 */
    uint64_t mCpuTick;							/* CPU时钟滴答，用64位无符号变量保存 */
    pthread_mutex_t mCpuTickMutext;				/* CPU时钟滴答互斥锁 */
};

#endif /* _APPTIMER_H_ */
